#include "stdio.h"
#include "string.h"
#include "board.h"
#include "rtu_mb.h"
#include "rtu_virtualIO.h"

#define HOLD_REG_MAX 125
static uint16_t hold_regs[HOLD_REG_MAX] = {0};

// 上传参数
extern ADS_Param   ADS_AIS[10];
extern rt_int32_t  soc_percent;
extern rt_int16_t  system_total_power;
extern rt_uint16_t modbus_get_phy_value(rt_uint16_t reg);

extern rt_uint16_t system_failed_code_1;
extern rt_uint16_t system_failed_code_2;
extern rt_uint16_t system_failed_code_3;

extern uint8_t rtu_master_print_enable;

extern enum operate_ctrl system_operate_ctrl;

int rtu_read_hold_regs(uint16_t addr, uint16_t num, uint16_t* buffer)
{
    uint8_t  index = 0, temp = 0;
    uint16_t io_start = 0, io_end = 0;

    if (rtu_master_print_enable)
        rt_kprintf("rtu read addr:%d num:%d\n", addr, num);

    for (index = 0; index < HOLD_REG_MAX; index++)
    {
        // 动态更新参数
        if (index < addr)
        {
            continue;
        }
        if (index > (addr + num))
        {
            break;
        }

        // 上传电压板10路电压
        if (index >= 0 && index < 10)
        {
            hold_regs[index] = (uint16_t)(ADS_AIS[index].vol_value);
        }
        else if (index >= 10 && index < 26)
        {
            // 上传4-20mA传感器参数
            temp = index - 10;
            if (temp == 4)
            {
                hold_regs[index] = (uint16_t)(system_total_power);
            }
            else if (temp == 15)
            {
                hold_regs[index] = (uint16_t)(soc_percent);
            }
            else
            {
                hold_regs[index] = (uint16_t)(modbus_get_phy_value(temp));
            }
        }
        else if (index == 26)
        {
            hold_regs[index] = (uint16_t)(system_failed_code_1);
        }
        else if (index == 27)
        {
            hold_regs[index] = (uint16_t)(system_failed_code_2);
        }
        else if (index == 28)
        {
            hold_regs[index] = (uint16_t)(system_failed_code_3);
        }
        else if (index == 29)
        {
            // 系统启动指令
            if (system_operate_ctrl == START)
            {
                hold_regs[index] = 1;
            }
            else
            {
                hold_regs[index] = 0;
            }
            rt_kprintf("index == 27:%d\n", hold_regs[index]);
        }
        else if (index == 30)
        {
            // 系统停机指令
            if (system_operate_ctrl == STOP)
            {
                hold_regs[index] = 1;
            }
            else
            {
                hold_regs[index] = 0;
            }
            rt_kprintf("index == 28:%d\n", hold_regs[index]);
        }
        else if (index == 31)
        {
            // 故障恢复
            if (system_operate_ctrl == FAULT_RESET)
            {
                hold_regs[index] = 1;
            }
            else
            {
                hold_regs[index] = 0;
            }
            rt_kprintf("index == 29:%d\n", hold_regs[index]);
        }
        else
        {
            hold_regs[index] = 0;
        }
    }

    if (addr > 124)
    {
        addr = addr - 125;
    }
    index = 0;
    if ((0 <= addr) && (addr < HOLD_REG_MAX))
    {
        io_start = addr;
        if ((addr + num) > (HOLD_REG_MAX))
        {
            io_end = HOLD_REG_MAX;
        }
        else
        {
            io_end = addr + num;
        }
        while (io_start < io_end)
        {
            buffer[index] = hold_regs[io_start];
            io_start++;
            index++;
        }
    }
    return index;
}

/**
 *  Extern 引用函数
 */
extern rt_bool_t lbo_system_ctrl_start(rt_uint16_t val);
extern rt_bool_t lbo_system_ctrl_stop(rt_uint16_t val);
extern rt_bool_t lbo_system_ctrl_reset(rt_uint16_t val);

int rtu_write_hold_regs(uint16_t addr, uint16_t num, uint16_t* buffer)
{
    uint16_t value = 0;
    if ((0 <= addr) && (addr < HOLD_REG_MAX))
    {
        value = rtu_aio_get_val(buffer, 0);
        rt_kprintf("rtu->write reg addr:%d value:%d\n", addr, value);
        if (addr >= 29 && addr < 32)
        {
            if (addr == 29)
            {
                //  系统启动
                lbo_system_ctrl_start(value);
            }
            if (addr == 30)
            {
                //  系统停止
                lbo_system_ctrl_stop(value);
            }
            if (addr == 31)
            {
                //  故障恢复
                lbo_system_ctrl_reset(value);
            }
        }
    }
    return num;
}